package com.xr.blog.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.xr.blog.dao.BlogCommentMapper;
import com.xr.blog.pojo.BlogArticle;
import com.xr.blog.pojo.BlogComment;
import com.xr.blog.service.BlogArticleService;
import com.xr.blog.service.BlogCommentService;
import com.xr.blog.service.SysUserService;
import com.xr.blog.tools.enums.CommentStatusEnum;
import com.xr.blog.tools.enums.CommentTargetTypeEnum;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.stereotype.Service;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;

import java.util.*;

import static java.util.stream.Collectors.toSet;


@Service
public class BlogCommentServiceImpl extends ServiceImpl<BlogCommentMapper, BlogComment> implements BlogCommentService {

    @Autowired
    private SysUserService userService;

    @Autowired
    private BlogArticleService articleService;

    @Override
    public IPage<BlogComment> findPageByArticleId(Page<BlogComment> page,Long articleId) {
        //查询当前文章下的已发布的一级评论
        IPage<BlogComment> commentPage = baseMapper.selectPage(page, new QueryWrapper<BlogComment>()
                .eq("target_type", CommentTargetTypeEnum.ARTICLE.getValue())
                .eq("target_id", articleId)
                .eq("status", CommentStatusEnum.PUBLISHED.getValue())
                .orderByDesc("id"));
        //获得一级评论的list集合
        List<BlogComment> list = commentPage.getRecords();
        //获取list里每条评论的id，并封装成set集合
        Set<Long> commentIds = list.stream().map(BlogComment::getId).collect(toSet());
        //查询子评论，子评论即各种回复，所以target_type字段位为2，target_id字段则为一级评论的id集合
        List<BlogComment> subComments = baseMapper.selectList(new QueryWrapper<BlogComment>()
                .eq("target_type", CommentTargetTypeEnum.COMMENT.getValue())
                .in(!commentIds.isEmpty(),"target_id", commentIds));

        /*子评论分组（遍历每一条当前文章的回复，新建一个map，将每条回复的target_id（即一级评论的id）作为key，
        使用compute函数实现当map中的key中不存在当前回复的target_id时，把当前target_id作为key，
        再新建一个list作为value，再调用packageComment方法设置好父级评论和评论文章后，将当前回复添加进list；
        如果key已存在，则再调用packageComment方法设置好父级评论和评论文章后封装评论后直接添加进value）

        最终数据格式：
        map:{"一级评论的id":[...list封装了该一级评论下的所有回复],"一级评论的id":[...list封装了该一级评论下的所有回复]}
        */
        Map<Long, List<BlogComment>> subCommentsMap = new HashMap<>();
        for (BlogComment subComment : subComments) {
            subCommentsMap.compute(subComment.getTargetId(), (k, v) -> {
                if (v == null) {
                    v = new ArrayList<>();
                }
                packageComment(subComment);
                v.add(subComment);
                return v;
            });
        }

        //遍历一级评论，设置评论的文章，并设置子评论集合，由当前评论的id作为key去subCommentsMap里取value
        for (BlogComment comment : list) {
            packageComment(comment);
            comment.setSubComments(subCommentsMap.get(comment.getId()));
        }
        return commentPage;
    }

    /**
     * 封装评论
     *
     * @param comment
     */
    private void packageComment(BlogComment comment) {
//        Long userId = comment.getUserId();
//        User user = userService.findUserById(userId);
//        comment.setUser(user);
//        Long replyUserId = comment.getReplyUserId();
//        if (Objects.nonNull(replyUserId)) {
//            User replyUser = userService.findUserById(replyUserId);
//            comment.setReplyUser(replyUser);
//        }
        if (CommentTargetTypeEnum.ARTICLE.getValue() == comment.getTargetType()) {
            BlogArticle article = articleService.findArticleById(comment.getTargetId());
            comment.setArticle(article);
        } else if (CommentTargetTypeEnum.COMMENT.getValue() == comment.getTargetType()) {
            BlogComment parentComment = baseMapper.selectById(comment.getTargetId());
            comment.setParentComment(parentComment);
            BlogArticle article = articleService.findArticleById(parentComment.getTargetId());
            comment.setArticle(article);
        }
    }

    @Override
    public List<BlogComment> findLatestComments(Integer count,boolean showCheck) {
        QueryWrapper<BlogComment> wrapper = new QueryWrapper<>();
        if (showCheck) {
            wrapper.in("status", CommentStatusEnum.CHECKING.getValue(), CommentStatusEnum.PUBLISHED.getValue());
        } else {
            wrapper.eq("status", CommentStatusEnum.PUBLISHED.getValue());
        }
        wrapper.orderByDesc("id");
        wrapper.last(" LIMIT " + count);
        List<BlogComment> list = baseMapper.selectList(wrapper);
        list.forEach(this::packageComment);
        return list;
//        return baseMapper.selectLatestComments(count,showCheck);
    }

    @Override
    public IPage<BlogComment> findCommentsByPage(Page<BlogComment> page, QueryWrapper wrapper) {
        IPage<BlogComment> iPage = baseMapper.selectPage(page, wrapper);
        if (iPage.getTotal() > 0) {
            iPage.getRecords().forEach(comment -> packageComment(comment));
        }
        return iPage;
//        return baseMapper.selectCommentPage(page,wrapper);
    }

    @Override
    public BlogComment findCommentById(Long id) {
        BlogComment comment = baseMapper.selectById(id);
        packageComment(comment);
        return comment;
//        return baseMapper.selectCommentById(id);
    }

    @Override
    public void deleteByArticleIds(List<Long> articleIds) {
        articleIds.forEach(articleId->{
            //查询当前文章下的已发布的一级评论
            List<BlogComment> commentList = baseMapper.selectList(new QueryWrapper<BlogComment>()
                    .eq("target_type", CommentTargetTypeEnum.ARTICLE.getValue())
                    .eq("target_id", articleId)
                    .eq("status", CommentStatusEnum.PUBLISHED.getValue())
                    .orderByDesc("id"));
            //获取list里每条评论的id，并封装成set集合
            Set<Long> commentIds = commentList.stream().map(BlogComment::getId).collect(toSet());
            //查询子评论，子评论即各种回复，所以target_type字段位为2，target_id字段则为一级评论的id集合
            List<BlogComment> subComments = baseMapper.selectList(new QueryWrapper<BlogComment>()
                    .eq("target_type", CommentTargetTypeEnum.COMMENT.getValue())
                    .in(!commentIds.isEmpty(),"target_id", commentIds));
            Set<Long> suCommentIds = subComments.stream().map(BlogComment::getId).collect(toSet());
            //删除一级评论
            baseMapper.deleteBatchIds(commentIds);
            //删除子评论
            baseMapper.deleteBatchIds(suCommentIds);
        });
    }


    @Override
    @CacheEvict(allEntries = true)
    public void clearCache() {
    }
}